<template>
  <div class="cd-listpanel">
    <Card class="search-wrap mb10" v-if="props.showSearch" ref="searchCardRef" dis-hover>
      <Form
        class="search-wrap-form"
        ref="tableSearchFormRef"
        :model="props.searchForm"
        :inline="props.inline"
        :label-width="props.labelWidth"
        @keydown.native.enter="onKeyboardQuery"
      >
        <!-- 普通查询条件插槽 -->
        <slot name="search"></slot>

        <!-- 可收起普通查询条件插槽 -->
        <div v-show="foldShow">
          <slot name="fold"></slot>
        </div>

        <!-- 高级查询条件插槽 -->
        <template v-if="isShowOtherQuery">
          <AdvancedQueryPanel
            ref="queryPanelRef"
            view-no="jy_eqdBasic1000tpm_list_query"
            :searchForm="props.searchForm"
          ></AdvancedQueryPanel>

          <!-- <QueryPanel
            v-show="isShowOtherQuery && showOtherQueryPanel"
            :queryViewNo="queryViewNo"
            :searchForm="searchForm"
            :slots="otherQueryPanelSlots"
            :isLocalQueryConfig="isLocalQueryConfig"
            :localQueryConfig="localQueryConfig"
            @on-render-call="queryFormCall"
            ref="queryPanel"
          >
            <template v-for="(item, index) in otherQueryPanelSlots">
              <div :key="index" :slot="item">
                <slot :name="item"></slot>
              </div>
            </template>
          </QueryPanel> -->
        </template>
      </Form>

      <Row class="search-wrap-btns" v-if="hasSearch">
        <Col class="tc" span="24">
          <Button type="primary" icon="ios-search" :loading="tableOptions.loading" @click="query">查询</Button>
          <Button class="ml10" v-if="showResetBtn" icon="md-refresh" @click="reset"> 重置 </Button>
          <slot name="otherBtn"></slot>

          <div class="text-btn-box">
            <Button class="text-info" v-if="props.showFold" type="text" @click="foldShow = !foldShow">
              <Icon :type="foldShow ? 'ios-arrow-up' : 'ios-arrow-down'" />
              {{ foldShow ? '隐藏' : '展开' }}
            </Button>

            <Button class="text-info" v-if="showOtherQueryPanel" type="text" @click="onViewConfigShowHandle('1')">
              <Icon type="md-flower" />
              设置
            </Button>

            <Button
              class="text-info"
              v-if="showOtherQueryPanel"
              type="text"
              @click="isShowOtherQuery = !isShowOtherQuery"
            >
              <Icon type="ios-search-outline" />
              <span>{{ isShowOtherQuery ? '普通查询' : '高级查询' }}</span>
            </Button>
          </div>
        </Col>
      </Row>
    </Card>

    <Card dis-hover>
      <!-- 操作按钮 -->
      <Row class="table-btnbar">
        <slot name="function"></slot>
      </Row>

      <!-- 表格 -->
      <Row class="table-box">
        <Col span="24">
          <Table
            ref="tableRef"
            :columns="columns"
            :border="props.border"
            :stripe="props.stripe"
            :show-header="props.showHeader"
            :size="props.size"
            :row-key="props.rowKey"
            :row-class-name="props.rowClassName"
            :highlight-row="props.highlightRow"
            :load-data="props.handleLoadData"
            :loading="tableOptions.loading"
            :height="tableOptions.tableHeight"
            :data="tableOptions.tableData"
            :no-data-text="tableOptions.noDataText"
            @on-sort-change="onSortChangeHandle"
            @on-selection-change="onSelectionChangeHandle"
            @on-cell-click="onCellClickHandle"
            @on-row-dblclick="onRowDblclickHandle"
          />
        </Col>
      </Row>

      <!-- 表格分页 -->
      <Row class="table-pager" v-if="pageShow">
        <Col :span="pageBarSpan">
          <Page
            size="small"
            show-elevator
            show-sizer
            transfer
            :current="tableOptions.pageNum"
            :page-size-opts="props.pageSizes"
            :page-size="tableOptions.currentPageSize"
            :total="tableOptions.count"
            :placement="props.pagePlacement"
            @on-page-size-change="onPageSizeChangeHandle"
            @on-change="onPageChangeHanlde"
          />
        </Col>
        <Col :span="24 - pageBarSpan" class="table-total-tip">
          <slot name="equNum" :equNum="tableOptions.equNum"></slot>
          当前共有
          <span class="text-success">{{ tableOptions.count }}</span>
          条数据 ，已选
          <span class="text-success">{{ selectedCount }}</span>
          条
        </Col>
      </Row>
    </Card>

    <!-- 查询条件 表头视图自定义配置弹窗 -->
    <CdUserViewConfig
      v-if="viewConfigParams.visible"
      v-model="viewConfigParams.visible"
      :type="viewConfigParams.type"
      :title="viewConfigParams.title"
      :width="viewConfigParams.width"
      :view-no="viewConfigParams.viewNo"
      :view-id="viewConfigParams.viewId"
      @after-save="onAfterUserViewConfigSaveHandle"
    />

    <!-- 序号列中回退提示内容 -->
    <div v-show="tooltipParams.visible" class="back-tip" :style="tooltipParams.style">
      {{ tooltipParams.reason }}
    </div>
  </div>
</template>

<script setup lang="ts">
import config from '@/config'
import { api_getTableConfig, api_getTableList } from '@/api/common'
import { isNotEmpty } from '@/utils/baseTool'
import { dateComputeByDay } from '@/utils/bussTool'
import { computed } from '@vue/reactivity'
import { onBeforeMount, reactive, ref, type Ref, resolveComponent } from 'vue'
import { Icon } from 'view-ui-plus'
import AdvancedQueryPanel from './AdvancedQueryPanel.vue'
import CdUserViewConfig from '@/components/bussiness/CdUserViewConfig'
import useDefineProps from './useDefineProps'
import useTableSort from './useTableSort'

// 父组件传入的属性
const props = defineProps(useDefineProps())

const emits = defineEmits([
  'on-reset',
  'on-afater-load',
  'on-select-change',
  'on-row-dblclick',
  'on-page-change',
  'on-query-able',
  'on-search-before',
  'on-search-after'
])

const isShowOtherQuery = ref(false)
const showResetBtn = ref(true)
const foldShow = ref(false)
const hasSearch = ref(true)

interface ITableOptions {
  tableData: any[]
  pageNum: number
  currentPageSize: number
  count: number
  noDataText: string
  tableHeight: number | string
  loading: boolean
  selectedId: string[]
  selectedRows: any[]
  equNum: number
  canQuery: boolean
}

const tableOptions: ITableOptions = reactive({
  tableData: ref([]),
  count: ref(0),
  pageNum: ref(1),
  currentPageSize: ref(props.pageSize),
  noDataText: ref('请设置查询条件后再进行查询'),
  tableHeight: ref(props.fixedHeight),
  loading: ref(false),
  selectedId: ref([]),
  selectedRows: ref([]),
  equNum: ref(0),
  canQuery: true
})

// 查询
const query = () => {
  tableOptions.canQuery = true
  tableOptions.pageNum = 1
  tableOptions.count = 0
  emits('on-query-able')
  if (tableOptions.canQuery) {
    emits('on-search-before')
    tableOptions.selectedId = []
    tableOptions.selectedRows = []
    loadDataHandle()
    emits('on-search-after')
  }
}

// 列表数据获取
const fetchParams = computed({
  get: (): any => {
    let _params: any = {}
    for (let key in props.searchForm) {
      let val = props.searchForm[key]

      if (isNotEmpty(val) && isNotEmpty(val.label)) {
        _params[key] = val.value
      } else if (val instanceof Array) {
        if (isNotEmpty(val[0])) {
          _params['begin' + key] = val[0]
          _params[key + 's'] = val[0]
        }
        if (isNotEmpty(val[1])) {
          _params['end' + key] = val[1]
          _params[key + 'e'] = val[1]
        }
      } else if (isNotEmpty(val) && enddateKeyValidate(key)) {
        _params[key] = dateValidate(val, 1)
      } else {
        _params[key] = val
      }
    }

    _params.pageNo = tableOptions.pageNum
    _params.pageSize = tableOptions.currentPageSize
    return _params
  },
  set: () => {}
})

// 结束检验日期校验
const enddateKeyValidate = (key: string) => {
  return (
    !props.notEndDateList.includes(key) &&
    ((key.endsWith('e') && !key.endsWith('date') && !key.endsWith('time') && !key.includes('Begin')) ||
      key.endsWith('End') ||
      key.startsWith('end'))
  )
}

const dateValidate = (date: string, day = 1) => {
  //判断传入的日期格式是yyyy-MM-dd
  let dateFormat = /^(\d{4})-(\d{2})-(\d{2})$/
  if (dateFormat.test(date)) {
    return dateComputeByDay(date, day)
  } else {
    return date
  }
}

const loadDataHandle = () => {
  tableOptions.loading = true
  api_getTableList(props.url, fetchParams.value).then((res) => {
    const { isSuccess, errorMsg, errmsg, data } = res
    if (isSuccess) {
      let tableData = []
      let pageData: any = null
      if (data.list) {
        pageData = data
        tableData = Object.assign([], pageData.list)
      } else {
        pageData = isNotEmpty(data.data) ? data.data : data
        // 在不分页的列表中response.data.data是列表数据
        if (Object.prototype.toString.call(data.data).includes('Array')) {
          tableData = Object.assign([], data.data)
        }
      }
      tableOptions.equNum = pageData?.list.length ? pageData.list[0].extparaa : 0
      emits('on-afater-load', pageData)

      // 计算序号
      if (isNotEmpty(tableData)) {
        for (let i = 0; i < tableData.length; i++) {
          let _index = i + (tableOptions.pageNum - 1) * tableOptions.currentPageSize + 1
          tableData[i].index = _index // 添加自定义序号

          if (props.idName !== 'id') {
            // id重新赋值为自定义字段
            tableData[i].id = tableData[i][props.idName]
          }
        }
      }

      // 总数
      tableOptions.count = pageData?.count || 0

      // 空数据文本
      if (tableOptions.count === 0) {
        tableData.noDataText = '没有找到符合条件的数据'
      }

      // 表格数据
      tableOptions.tableData = tableData

      tableOptions.loading = false
    } else {
      window.$Message.error(errorMsg || errmsg)
    }
  })
}

// 回车查询
const keyboardSearchOn = computed(() => config.openEnterSearch || props.openEnterSearch)
const onKeyboardQuery = () => {
  if (keyboardSearchOn) query()
}

// 查询表单重置
const tableSearchFormRef = ref()
const reset = () => {
  tableSearchFormRef.value.resetFields()
  emits('on-reset')
}

const queryPanelRef = ref()
const getQueryFormHandle = () => {
  console.log('高级查询条件获取方法调用')
}

// 获取表头
let columns: Ref<any[]> = ref([])
const getColumnsHandle = (): void => {
  columns.value = []
  if (props.isLocalColumns) {
    getLocalColumns()
  } else {
    if (props.tableViewNo) {
      getRemoteColumns(props.tableViewNo)
    } else {
      window.$Message.warning('表头视图不能为空')
    }
  }
}

// 本地表头获取
const getLocalColumns = () => {
  reSetColumns(props.localColumns)
}

// 服务端表头获取
const getRemoteColumns = (viewNo: string) => {
  api_getTableConfig(viewNo).then((res) => {
    const { isSuccess, errorMsg, errmsg, data } = res || {}
    if (isSuccess) {
      reSetColumns(data.columns)
    } else {
      window.$Message.error(errorMsg || errmsg)
    }
  })
}

// 将获取到的本地/服务器表头属性重写
interface IRenderParams {
  row: any
  index?: number
}
const tooltipParams = reactive({
  visible: false,
  reason: '',
  style: ''
})

// 排序相关方法引入
const { sortSet, webSortHandle, remoteSortHandle } = useTableSort(config, props)

const reSetColumns = (resetColumns: any) => {
  if (props.customColumns.length) {
    pushCusColumnsHandle(resetColumns)
  }

  if (props.showIndex) {
    columns.value.push({
      title: '序号',
      width: props.indexColWidth,
      align: 'center',
      fixed: props.isColFix ? 'left' : '',
      render: (h: any, { row }: IRenderParams) => {
        const tooltipShow = row.isBack === '1' && props.indexTooltip
        const showOkIconCondition = 'params.row.' + props.okIconGrammar

        // 自定义回退信息气泡提示
        const _toolTip = tooltipShow
          ? h(
              'div',
              {
                style: { display: 'inline-block', padding: '2px 5px' },
                onMouseenter: (e: any) => {
                  console.log(e, 11)
                  tooltipParams.visible = true
                  tooltipParams.reason = row[props.reasonKey] || ''
                  tooltipParams.style = `top:${e.clientY - e.offsetY}px;left:${e.clientX - e.offsetX + 36}px;`
                },
                onMouseleave: () => {
                  tooltipParams.visible = false
                }
              },
              [h(Icon, { type: 'md-arrow-back' })]
            )
          : ''

        const _checkMark =
          isNotEmpty(props.okIconGrammar) && eval(showOkIconCondition) ? h(Icon, { type: 'md-checkmark' }) : ''

        return h('div', [h('span', [_checkMark, row.ROWNUM_ || row.index]), _toolTip])
      }
    })
  }

  // 插入多选框
  if (props.showCheckBox) {
    columns.value.push({
      type: 'selection',
      width: 50,
      align: 'center',
      fixed: props.isColFix ? 'left' : ''
    })
  }

  // 插入操作列
  if (props.tableAction && props.tableAction.title) {
    columns.value.push(props.tableAction)
  }

  // 枚举自定义项
  let colRenderMap: any = {}
  let colRenderLen = props.colRenders.length
  if (colRenderLen > 0) {
    for (let i = 0; i < colRenderLen; i++) {
      let item: any = props.colRenders[i]
      colRenderMap[item.key] = item
    }
  }

  // 插入本地/服务端表头
  for (let i = 0; i < resetColumns.length; i++) {
    let column = resetColumns[i]
    const colRenderItem = colRenderMap[column.key || column.name] // 获取与自定义匹配项
    if (column.id && colRenderItem && colRenderItem[column.key || column.name]?.showType) {
      // 隐藏列操作，手动showType值为hidden
      column.showType = colRenderItem[column.name].showType
    }

    if (column.showType === 'hidden') {
      continue
    }

    if (column.id) {
      column.title = column.comments
      column.key = column.name
      column.width = column.compLength
      column.fixed = props.isColFix && column.isFreeze === '1' ? 'left' : ''

      if (colRenderItem) {
        column = { ...column, ...colRenderItem }
      } else {
        // 设置字体颜色
        // 当有自定义render函数存在时，避免被重新覆盖，估添加上自定义render函数是否存在判断（场景：自定义设置列表属性时）
        if (column.labelColor) {
          column.render = function (h: any, { row }: { row: any }) {
            return h(
              'span',
              {
                style: { color: column.labelColor }
              },
              row[column.key]
            )
          }
        }
      }
    }
    column.align = 'center'
    column.minWidth = column.minWidth || 100

    // 排序设置
    // if (allSortAble.value) {
    //   if (column.title !== '序号' && column.title !== '操作' && column.title !== '选中') {
    //     column.sortable = 'custom'
    //     addSortColumnsWidth(column, 10)
    //   }
    // } else {
    //   if (props.sortAbleCols.includes(column.key)) {
    //     column.sortable = 'custom'
    //     addSortColumnsWidth(column, 10)
    //   }
    // }
    sortSet(column)
    columns.value.push(column)
  }
}

// 插入自定义列
const pushCusColumnsHandle = (columns: any) => {
  columns.value.push(...props.customColumns)
}

interface ISortParmas {
  column: any
  key: string
  order: string
}
// 排序回调
const onSortChangeHandle = (params: ISortParmas) => {
  if (props.webOrderBy) {
    webSortHandle(params, tableOptions)
  } else {
    remoteSortHandle(params, fetchParams)
    loadDataHandle()
  }
}

// 表格高度处理
const searchCardRef = ref()
const autoHeightHandle = () => {
  if (props.isTableAutoHeight) {
    const searchCard = searchCardRef.value?.$el
    const headerCon = document.querySelector('.ivu-table-header')
    const siderTop = document.querySelector('.left-sider-top')
    let top = 90
    if (searchCard) {
      /* 搜索框高度 */
      // 屏蔽ts报错：类型“Element”上不存在属性“offsetHeight”。ts(2339)
      top += (searchCard as HTMLDivElement).offsetHeight
    }
    if (headerCon) {
      /* 页头控件高度 */
      top += (headerCon as HTMLDivElement).offsetHeight
    }
    if (siderTop) {
      /* 页标签 高度 */
      top += (siderTop as HTMLDivElement).offsetHeight
    }

    let tableHeight = window.innerHeight - top
    tableHeight = tableHeight < 400 ? 400 : tableHeight

    // 表格高度，无固定高度传入时，使用计算出来的高度
    tableOptions.tableHeight = props.fixedHeight !== 'auto' ? props.fixedHeight : tableHeight
  } else {
    if (config.sysCode === 'ZJ-JH-SCDEAP') {
      tableOptions.tableHeight = '500'
    }
  }
}

// 表格选择回调
const onSelectionChangeHandle = (selection: any[]) => {
  tableOptions.selectedRows = selection
  tableOptions.selectedId = selection.map((item) => item[props.idName])
  emits('on-select-change', tableOptions.selectedRows, tableOptions.selectedId)
}

// 单元个点击回调
const onCellClickHandle = (row: any, column: any, data: any, event: any) => {
  if (isNotEmpty(data) && config.isCellClick) {
    const input = document.createElement('input')
    document.body.appendChild(input)
    input.setAttribute('value', data)
    input.select()
    if (document.execCommand('copy')) {
      window.$Message.success('复制成功')
    }
    document.body.removeChild(input)
  }
}

// 双击行回调
const onRowDblclickHandle = (row: any, index: string) => {
  emits('on-row-dblclick', row, index)
}

const selectedCount = computed(() => tableOptions.selectedRows.length)
// 分页 展示条数切换回调
const onPageSizeChangeHandle = (pageSize: number) => {
  tableOptions.currentPageSize = pageSize
  loadDataHandle()
}
// 分页 页数切换回调
const onPageChangeHanlde = (page: number) => {
  tableOptions.pageNum = page

  loadDataHandle()
  emits('on-page-change')
}

const viewConfigParams = reactive({
  visible: false,
  title: '查询条件自定义字段',
  width: '500',
  viewNo: '',
  viewId: '',
  type: ''
})

// 条件/表格视图自定义窗口
const onViewConfigShowHandle = (type: string) => {
  viewConfigParams.visible = true
  viewConfigParams.type = type
  viewConfigParams.title = type === '0' ? '查询条件自定义字段' : '表格自定义展示字段'
  viewConfigParams.viewNo = type === '0' ? props.queryViewNo : props.tableViewNo
  viewConfigParams.viewId = ''
}

// 自定义设置成功回调
const onAfterUserViewConfigSaveHandle = (type: string) => {
  if (type === '0') {
    getQueryFormHandle()
  } else {
    getColumnsHandle()
  }
}

defineExpose({ tableOptions }) // 属性暴露

onBeforeMount(() => {
  getColumnsHandle()
  autoHeightHandle()
})
</script>

<style lang="less">
@import url('./style.less');
</style>
